#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define List(i) list[i-1]
typedef struct ksorted
{
	int *a;
	int i,n,v;
}kmerge;

int kmergeheapify(kmerge **list,int p,int n)
{
	int i,j,k;
	int l,r;
	kmerge *temp;
	l=2*p;
	r=(l==n)?l:l+1;
	temp=List(p);
	if(l<=n)
	{
		k=(List(l)->v<List(r)->v)?r:l;
		if(List(p)->v<List(k)->v) List(p)=List(k),List(k)=temp,kmergeheapify(list,k,n);
		return 0;
	}
}


int kbuildheap(kmerge **list,int n)
{
	int i;
	for(i=n/2;i>0;i--)
	{
		kmergeheapify(list,i,n);
	}
}

int extractmax(kmerge **list,int n)
{
	int i,temp;
	temp=List(1)->v;
	List(1)->i+=1;
	List(1)->v=(List(1)->i<List(1)->n)?List(1)->a[List(1)->i]:-1;
	kmergeheapify(list,1,n);
	return temp;
}

int kmergesort(kmerge **list,int n,int *b,int m)
{
	int i,temp;
	kbuildheap(list,n);
	for(i=0;i<m;i++) b[i]=extractmax(list,n);
	return 0;
}

int main()
{
	int i,j,k;
	int nt,mt=0;
	int *n;
	int **a;
	int *b;
	kmerge **list;
	scanf("%d",&nt);
	n=(int *)malloc(nt*sizeof(int));
	for(i=0;i<nt;i++) scanf("%d",&n[i]);
	a=(int **)malloc(nt*sizeof(int *));
	for(i=0;i<nt;i++) a[i]=(int *)malloc(n[i]*sizeof(int));
	for(i=0;i<nt;i++) for(j=0;j<n[i];j++) scanf("%d",&a[i][j]);
	list=(kmerge **)malloc(nt*sizeof(kmerge *));
	for(i=0;i<nt;i++) list[i]=(kmerge *)malloc(sizeof(kmerge));
	for(i=0;i<nt;i++)
	{
		list[i]->a=a[i];
		list[i]->n=n[i];
		list[i]->i=0;
		list[i]->v=a[i][0];
	}
	for(i=0;i<nt;i++) mt+=n[i];
	b=(int *)malloc(mt*sizeof(int));
	kmergesort(list,nt,b,mt);
	for(i=0;i<mt;i++) printf("%d ",b[i]);
	for(i=0;i<nt;i++) free(a[i]);
	for(i=0;i<nt;i++) free(list[i]);
	free(a);
	free(list);
	free(n);
	free(b);
	return 0;
}


